#include "sock.hpp"
#include "common.hpp"
#include "addr.hpp"
#include <unistd.h>
#include <algorithm>
#include <poll.h>
class pollserver
{

    const static int defaultfd = -1;

public:
    pollserver(int port) : _is_running(0), _listenfd(make_unique<Tcpsocket>())
    {
        _listenfd->arrangesock(port);
        // 对每次更新select 的rfd数组进行初始化：
       for (int i = 0; i < 4096; i++)
        {
            _fds[i].fd = defaultfd;
            _fds[i].events = 0;
            _fds[i].revents = 0;

        }

        _fds[0].fd = _listenfd->Fd();
        _fds[0].events = POLLIN;
    }

    void start()
    {
        _is_running = 1;
        while (_is_running)
        {

            int n = poll(_fds,4096,-1);//阻塞等待
            if (n > 0)
            {
                use_log(loglevel::DEBUG) << "读（写）事件就绪!";
                Dispatcher();
            }
            else if (n == 0)
            {

                use_log(loglevel::DEBUG) << "等待超时!";
                break;
            }
            else
            {
                cout << "错误 ：" << n << endl;
                use_log(loglevel::DEBUG) << "select 错误";
                break;
            }
        }
    }

    void Dispatcher()
    {
        for (int i = 0; i < 4096; i++)
        {
            if (_fds[i].fd == defaultfd)
                continue;
            // 后面对数组中有效的fd进行检查是否就绪：分listenfd与普通fd：
            if (_fds[i].revents&POLLIN) 
            {

                if (_fds[i].fd == _listenfd->Fd())
                    Acceper(); // 去等待队列接收新链接
                else
                    Recver(_fds[i].fd, i); // 读取对应缓冲区数据
            }
        }
    }

    void Acceper()
    {
        inetaddr client;
        int newfd = _listenfd->Accept(&client);
        int i = 0;
        for (i = 0; i < 4096; i++)
        {
            if (_fds[i].fd == defaultfd)
            {
                _fds[i].fd = newfd;
                _fds[i].events=POLLIN;
                break;
            } // 找到空的位置进行新的fd填入
        }
       
        if (i==4096)
        {

            use_log(loglevel::DEBUG) << "select full";
            close(newfd);
        }
    }

    void Recver(int fd, int pos)
    {
        char buf[1024] = {0};
        int n = recv(fd, buf, sizeof(buf) - 1, 0);
        if (n > 0)
        {
            buf[n] = 0;
            cout << " client say @  : " << buf << endl;
        }
        else if (n == 0)
        {
            use_log(loglevel::DEBUG) << "client exit";
            close(fd);
          _fds[pos].fd = defaultfd;
          _fds[pos].events=0;
          _fds[pos].revents=0;
        }

        else
        {

            use_log(loglevel::DEBUG) << "Recv error";
            close(fd);
          _fds[pos].fd = defaultfd;
          _fds[pos].events=0;
          _fds[pos].revents=0;
        }
    }
    void stop()
    {
        _is_running = 0;
    }
    ~pollserver() {}

private:
    bool _is_running;
    unique_ptr<Socket> _listenfd;
    struct pollfd _fds[4096];//这里也可以搞成指针结合realloc进行扩容
};
